/*---------------------------------------------------------
  Oren Attia  - 29074333
  Doron Segal - 
  ---------------------------------------------------------*/

#include <windows.h>
#include <commctrl.h>
#include "resource.h"

#define IDC_MAIN_SELECT 				10001
#define IDC_MAIN_TOOL					10002
#define IDC_MAIN_STATUS					10003

#define IDC_BLACK                       20001
#define IDC_BLUE                        20002
#define IDC_GREEN                       20003
#define IDC_CYAN                        20004
#define IDC_RED                         20005
#define IDC_MAGENTA                     20006
#define IDC_YELLOW                      20007
#define IDC_WHITE                       20008

#define ID_DRAW_LINE                    30001
#define ID_DRAW_SQUARE                  30002
#define ID_DRAW_ELLIPSE                 30003

#define ID_CLEAR                        40001
#define ID_FILE_SAVEAS                  40002
#define ID_FILE_OPEN                    40013
#define ID_FILL_SHAPE                   40004
#define ID_EMPTY_SHAPE                  40005
#define ID_UNDO                         40006
#define ID_REDO                         40007
#define ID_EXIT                         40008

#define ID_COLOR_FRAME                  41001 
#define ID_CHOOSE_COLOR                 41002  
#define ID_CHOOSE_SHAPE                 41003

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

HINSTANCE gHinst;
COLORREF gColor;

const char g_szClassName[] = "PaintBrush_WindowClass";

static int pShape=ID_DRAW_LINE; 
static RECT rcMain,rcClient,rcShape;
static HBRUSH hBrush,holdBrush ;
static HPEN hPen,holdPen ;

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASSEX wc;
	HWND hwnd;
	MSG Msg;

	//InitCommonControls();

	wc.cbSize		 = sizeof(WNDCLASSEX);
	wc.style		 = CS_HREDRAW | CS_VREDRAW ;
	wc.lpfnWndProc	 = WndProc;
	wc.cbClsExtra	 = 0;
	wc.cbWndExtra	 = 0;
	wc.hInstance	 = hInstance;
	wc.hIcon		 = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_PAINT));
	wc.hCursor		 = LoadCursor(gHinst, IDC_CROSS);
	wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
	wc.lpszMenuName  = NULL;											
	wc.lpszClassName = g_szClassName;
	wc.hIconSm		 = LoadIcon(NULL, IDI_APPLICATION);

	gHinst = hInstance;

	if(!RegisterClassEx(&wc))
	{
		MessageBox(NULL, "Window Registration Failed!", "Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	hwnd = CreateWindowEx(
		0,
		g_szClassName,
		"HIT Final Project - Paint Brush Application",
		WS_OVERLAPPEDWINDOW ,
		CW_USEDEFAULT, CW_USEDEFAULT, 623,470,
		NULL, NULL, hInstance, NULL);

	if(hwnd == NULL)
	{
		MessageBox(NULL, "Window Creation Failed!", "Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);

	while(GetMessage(&Msg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}
	return Msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	static int   cxIcon, cyIcon, cxClient, cyClient ;
	static HWND hSelection;
	static HICON hIcon ;

    HDC         hdc = (HDC) wParam ;
	HINSTANCE   hInstance ;
	HWND hTool,hStatus,hDefaultColor;	
    PAINTSTRUCT ps,psSelection ;
	RECT		rcColors;
			
	int          x, y ;


	switch(msg)
	{
	 case WM_CREATE:
		 {
			HFONT hfDefault;
			TBBUTTON tbb[8];
			TBADDBITMAP tbab;

			int statwidths[] = {100, -1};


			hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;
			hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_PAINT)) ;
			cxIcon = GetSystemMetrics (SM_CXICON) ;
			cyIcon = GetSystemMetrics (SM_CYICON) ;


			// Create Selection SubWindow
			hSelection = CreateWindow (TEXT ("static"),"SelectionWindow",WS_CHILD | WS_VISIBLE | SS_WHITERECT | WS_BORDER,0, 0, 0, 0,hwnd, (HMENU) 9, hInstance, NULL) ;


			// Create Toolbar
			hTool = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
				hwnd, (HMENU)IDC_MAIN_TOOL, GetModuleHandle(NULL), NULL);
			if(hTool == NULL)
				MessageBox(hwnd, "Could not create tool bar.", "Error", MB_OK | MB_ICONERROR);

			// Send the TB_BUTTONSTRUCTSIZE message, which is required for
			// backward compatibility.
			SendMessage(hTool, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON),0);
			
			tbab.hInst = HINST_COMMCTRL;
			tbab.nID = IDB_STD_LARGE_COLOR;
			SendMessage(hTool, TB_ADDBITMAP,8, (LPARAM)&tbab);

			ZeroMemory(tbb, sizeof(tbb));
			tbb[0].iBitmap = STD_FILENEW;
			tbb[0].iString = "Clear";
			tbb[0].fsState = TBSTATE_ENABLED;
			tbb[0].fsStyle = TBSTYLE_BUTTON;
			tbb[0].idCommand = ID_CLEAR;

			tbb[1].iBitmap = STD_FILEOPEN;
			tbb[1].iString = "Open";
			tbb[1].fsState = TBSTATE_ENABLED;
			tbb[1].fsStyle = TBSTYLE_BUTTON;
			tbb[1].idCommand = ID_FILE_OPEN;

			tbb[2].iBitmap = STD_FILESAVE;
			tbb[2].iString = "Save";
			tbb[2].fsState = TBSTATE_ENABLED;
			tbb[2].fsStyle = TBSTYLE_BUTTON;
			tbb[2].idCommand = ID_FILE_SAVEAS;

			tbb[3].iBitmap = IDI_PAINT;
			tbb[3].iString = "Fill Shape";
			tbb[3].fsState = TBSTATE_ENABLED;
			tbb[3].fsStyle = TBSTYLE_CHECK;
			tbb[3].idCommand = ID_FILL_SHAPE;

			tbb[4].iBitmap = IDI_PAINT;
			tbb[4].iString = "Empty Shape";
			tbb[4].fsState = TBSTATE_ENABLED;
			tbb[4].fsStyle = TBSTYLE_CHECK;
			tbb[4].idCommand = IDC_MAIN_SELECT; // ID_EMPTY_SHAPE;

			tbb[5].iBitmap = STD_UNDO;
			tbb[5].iString = "Undo";
			tbb[5].fsState = TBSTATE_ENABLED;
			tbb[5].fsStyle = TBSTYLE_BUTTON;
			tbb[5].idCommand = ID_UNDO;

			tbb[6].iBitmap = STD_REDOW;
			tbb[6].iString = "Redo";
			tbb[6].fsState = TBSTATE_ENABLED;
			tbb[6].fsStyle = TBSTYLE_BUTTON;
			tbb[6].idCommand = ID_REDO;

			tbb[7].iBitmap = IDI_PAINT;
			tbb[7].iString = "Exit";
			tbb[7].fsState = TBSTATE_ENABLED;
			tbb[7].fsStyle = TBSTYLE_BUTTON;
			tbb[7].idCommand = ID_EXIT;

			SendMessage(hTool, TB_ADDBUTTONS, sizeof(tbb)/sizeof(TBBUTTON), (LPARAM)&tbb);


			// Create Status bar
			hStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL,
				WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0,
				hwnd, (HMENU)IDC_MAIN_STATUS, GetModuleHandle(NULL), NULL);

			SendMessage(hStatus, SB_SETPARTS, sizeof(statwidths)/sizeof(int), (LPARAM)statwidths);
			SendMessage(hStatus, SB_SETTEXT,0, (LPARAM)"Paint Brush Status");



			// Create Choose Shape Windows
			CreateWindow(TEXT("button"), TEXT("Choose Shape:"), WS_CHILD | WS_VISIBLE | BS_GROUPBOX ,2, 55,110, 125, hwnd, (HMENU) ID_CHOOSE_SHAPE, gHinst, NULL);
			
			CreateWindow(TEXT("button"), TEXT("Line"),WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON ,7, 80, 100, 25, hwnd, (HMENU)ID_DRAW_LINE , gHinst, NULL);
			CreateWindow(TEXT("button"), TEXT("Square"),WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,7, 110, 100, 25, hwnd, (HMENU)ID_DRAW_SQUARE , gHinst, NULL);
			CreateWindow(TEXT("button"), TEXT("Ellipse"),WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,7, 140, 100, 25, hwnd, (HMENU)ID_DRAW_ELLIPSE , gHinst, NULL);

			// Create Choose Colors Windows
			CreateWindow(TEXT("button"), TEXT("Choose Color:"), WS_CHILD | WS_VISIBLE | BS_GROUPBOX,2, 180,110, 190, hwnd, (HMENU) ID_CHOOSE_COLOR, gHinst, NULL);

			hDefaultColor = CreateWindow(TEXT("button"), TEXT("Black"),WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON ,7, 205, 100, 25, hwnd, (HMENU)IDC_BLACK , gHinst, NULL);
			CreateWindow(TEXT("button"), TEXT("Blue"),WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON  ,7, 225, 100, 25, hwnd, (HMENU)IDC_BLUE , gHinst, NULL);
			CreateWindow(TEXT("button"), TEXT("Green"),WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,7, 245, 100, 25, hwnd, (HMENU)IDC_GREEN , gHinst, NULL);
			CreateWindow(TEXT("button"), TEXT("Cyan"),WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON ,7, 265, 100, 25, hwnd, (HMENU)IDC_CYAN , gHinst, NULL);
			CreateWindow(TEXT("button"), TEXT("Red"),WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | BN_CLICKED ,7, 285, 100, 25, hwnd, (HMENU)IDC_RED , gHinst, NULL);
			CreateWindow(TEXT("button"), TEXT("Magenta"),WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,7, 305, 100, 25, hwnd, (HMENU)IDC_MAGENTA , gHinst, NULL);
			CreateWindow(TEXT("button"), TEXT("Yellow"),WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,7, 325, 100, 25, hwnd, (HMENU)IDC_YELLOW , gHinst, NULL);
			CreateWindow(TEXT("button"), TEXT("White"),WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON  ,7, 345, 100, 25, hwnd, (HMENU)IDC_WHITE , gHinst, NULL);

			SendMessage(hDefaultColor, BM_SETCHECK, BST_CHECKED,1);
		 }
		 break;
     case WM_CTLCOLORSTATIC: 
		 {   
			 //SetBkMode( hdc, TRANSPARENT ); 
			 SetBkColor(hdc,RGB(255,255,255));
			 SetTextColor( hdc, RGB( 0,0,0 ) );   
			 return ( INT_PTR )GetStockObject( HOLLOW_BRUSH); 
		 }
		 break;
     case WM_LBUTTONDOWN:
		 {   
		 }
		 break;
     case WM_MOUSEMOVE:
		 {
		 }
		 break;
     case WM_LBUTTONUP:
		 {
		 }
	     break;
	 case WM_SIZE:
		 {
			HWND hTool;
			RECT rcTool;
			int iToolHeight;

			HWND hStatus;
			RECT rcStatus;
			int iStatusHeight;

			RECT rcClient;

			cxClient = LOWORD (lParam) ;
			cyClient = HIWORD (lParam) ;

			// Size of rcMain main window
			GetWindowRect(hwnd, &rcMain);

			// Size Selection Window
			MoveWindow (hSelection, 0, 0, 115, 380, TRUE) ;


			// Size toolbar and get height
			hTool = GetDlgItem(hwnd, IDC_MAIN_TOOL);
			SendMessage(hTool, TB_AUTOSIZE, 0, 0);

			GetWindowRect(hTool, &rcTool);
			iToolHeight = rcTool.bottom - rcTool.top;


			// Size status bar and get height
			hStatus = GetDlgItem(hwnd, IDC_MAIN_STATUS);
			SendMessage(hStatus, WM_SIZE, 0, 0);

			GetWindowRect(hStatus, &rcStatus);
			iStatusHeight = rcStatus.bottom - rcStatus.top;
		 }
	     break;
	 case WM_PAINT: 
		 {
			if (rcMain.right < 623 || rcMain.bottom < 470)
			{
				 MoveWindow(hwnd,rcMain.left,rcMain.top,623,470,TRUE);
			}

			hdc = BeginPaint (hwnd, &ps) ;

			for (y = 0 ; y < cyClient ; y += cyIcon)
			   for (x = 0 ; x < cxClient ; x += cxIcon)
					DrawIcon (hdc, x, y, hIcon);

				hBrush = CreateSolidBrush(gColor);
				hPen = CreatePen(PS_SOLID, 2, RGB(0, 76, 0));
				holdPen = SelectObject(hdc, hPen);
				holdBrush = (HBRUSH) SelectObject(hdc, hBrush);

				Rectangle(hdc, 0, 380, 115.5, 410);
				

				SelectObject(hdc, holdBrush);
				SelectObject(hdc, holdPen);

				DeleteObject(holdPen);
				DeleteObject(holdBrush);
				DeleteObject(hPen);
				DeleteObject(hBrush);

			EndPaint (hwnd, &ps) ;
		 }
	     break;
	 case WM_DRAWITEM :
		 {
		 }
	     break;
	 case WM_CLOSE:
		 {
			 DestroyWindow(hwnd);
		 }
		 break;
	 case WM_DESTROY:
		 {
			 PostQuitMessage(0); 
		 }
		 break;
	 case WM_COMMAND:
		 {
			 switch(LOWORD(wParam))
			 {
				case ID_CLEAR:
					
				break;
				case ID_FILE_OPEN:
					//DoFileOpen(hwnd);
				break;
				case ID_FILE_SAVEAS:
					//DoFileSave(hwnd);
				break;
				break;
				case ID_DRAW_LINE:
					pShape=ID_DRAW_LINE;
				break; 
				case ID_DRAW_SQUARE:
					pShape=ID_DRAW_SQUARE;
				break; 
				case ID_DRAW_ELLIPSE:
					pShape=ID_DRAW_ELLIPSE;
				break; 
				case ID_EXIT:
					SendMessage(hwnd,WM_CLOSE,0,0L);
				break; 
			 }

			if (HIWORD(wParam) == BN_CLICKED) 
			{
				switch (LOWORD(wParam)) 
				{
					case IDC_BLACK:
						gColor = RGB(0, 0, 0);
					break; 
					case IDC_BLUE:
						gColor = RGB(0, 76, 255);
					break; 
					case IDC_GREEN:
						gColor = RGB(34, 139, 34);
					break; 
					case IDC_CYAN:
						gColor = RGB(0, 255, 255);
					break; 
					case IDC_RED:
						gColor = RGB(255, 0, 0);
					break; 
					case IDC_MAGENTA:
						gColor = RGB(255, 0, 255);
					break; 
					case IDC_YELLOW:
						gColor = RGB(255, 255, 0);
					break; 
					case IDC_WHITE:
						gColor = RGB(255, 255, 255);
					break; 
				}
				InvalidateRect(hwnd, NULL, FALSE);
			}
		 }
		 break;		
	 default:
		 return DefWindowProc(hwnd, msg, wParam, lParam);
	}

return 0;
}
